unit ec_showmessage;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, Buttons,
  ExtCtrls, ec_base, LCLTranslator, languagehelper;

type

  { TECShowMessageFrame }

  TECShowMessageFrame = class(TECBaseFrame)
    BackgroundComboBox: TComboBox;
    BackgroundLabel: TLabel;
    AdditionalSettingPanel: TPanel;
    BackgroundPanel: TPanel;
    PositionComboBox: TComboBox;
    PositionLabel: TLabel;
    PositionPanel: TPanel;
    BatchEntryCheckBox: TCheckBox;
    TextSizePanel: TPanel;
    FaceLabel: TLabel;
    FaceSpeedButton: TSpeedButton;
    TextMemo: TMemo;
    TextLabel: TLabel;
    procedure FaceSpeedButtonClick(Sender: TObject);
  private
    FaceFilename: String;
    FaceIndex: Integer;
    procedure UpdateFace;
    procedure InitialSetUp;
    procedure ResizeMemo;
    procedure UpdateLinePosition;
  public
    procedure InitNew; override;
    procedure InitExisting; override;
    procedure MakeResultingCommand; override;
    procedure UpdateLanguage(Code: String); override;
  end;

const
  NUM_CHARS_WITH_FACE = 43;
  NUM_CHARS_WITHOUT_FACE = 55;

var
  ECShowMessageFrame: TECShowMessageFrame;

implementation

{$R *.lfm}

uses
  fpjson, constants, globals, gamefont, comboboxhelper, imageselection;

{ TECShowMessageFrame }

procedure TECShowMessageFrame.FaceSpeedButtonClick(Sender: TObject);
begin
  if ImageSelectionForm.ShowFaceSelection(FaceFilename, FaceIndex) then begin
    FaceFilename := ImageSelectionForm.SelectedFilename;
    FaceIndex := ImageSelectionForm.Index;
    UpdateFace;
  end;
end;

procedure TECShowMessageFrame.UpdateFace;
var
  FacePng: TBitmap;
begin
  FaceSpeedButton.Glyph.Clear;

  if FaceFilename <> '' then begin
    FacePng := Game.GetFace(FaceFilename, FaceIndex, 74);
    FaceSpeedButton.Glyph.Assign(FacePng);
    FacePng.Free;
  end;

  UpdateLinePosition;
end;

procedure TECShowMessageFrame.InitialSetUp;
begin
  ResizeMemo;

  FillMessageBgTypeCombobox(BackgroundComboBox);
  FillMessagePosCombobox(PositionComboBox);
end;

procedure TECShowMessageFrame.ResizeMemo;
var
  Margin: Integer;
begin
  with TextMemo.Font do begin
    BeginUpdate;
    Name := GetMonospacedFontName;
    Size := GetMonospacedFontSize;
    EndUpdate;
  end;
  Margin := TextMemo.Scale96ToForm(8); // TODO find a way not to hard-code
  ResizeMemoForFont(TextMemo, NUM_CHARS_WITHOUT_FACE, 4);
  //only use height; for width, use the TextSizePanel
  TextMemo.Width := Width - TextMemo.Left - Margin;
end;

procedure TECShowMessageFrame.UpdateLinePosition;
var
  X: Integer;
  NumChars: Integer;
begin
  if FaceFilename = '' then
     NumChars := NUM_CHARS_WITHOUT_FACE
  else
    NumChars:= NUM_CHARS_WITH_FACE;

  X := FindXPosOverMemo(TextMemo, NumChars);
  if akRight in TextSizePanel.Anchors then //RTL
    TextSizePanel.Left := TextMemo.Left + TextMemo.Width - X
  else
    TextSizePanel.Left := TextMemo.Left + X;
end;

procedure TECShowMessageFrame.InitNew;
begin
  FaceFilename := '';
  FaceIndex := 0;

  InitialSetUp;
  UpdateLinePosition;

  BackgroundComboBox.ItemIndex := 0;
  PositionComboBox.ItemIndex := 2;
end;

procedure TECShowMessageFrame.InitExisting;
  procedure InitSettings;
  var
    Params: TJSONArray;
    Bg, Pos: Integer;
  begin
    Params := GetFirstParams;

    FaceFilename := '';
    if (Params <> nil) and (Params.Count >= 1) and (Params[0].JSONType = jtString) then
       FaceFilename := Params.Strings[0];

    FaceIndex := 0;
    if (Params <> nil) and (Params.Count >= 2) and (Params[1].JSONType = jtNumber) then
       FaceIndex := Params.Integers[1];

    Bg := 0;
    if (Params <> nil) and (Params.Count >= 3) and (Params[2].JSONType = jtNumber) then
       Bg := Params.Integers[2];
    BackgroundComboBox.ItemIndex := Bg;

    Pos := 2;
    if (Params <> nil) and (Params.Count >= 4) and (Params[3].JSONType = jtNumber) then
       Pos := Params.Integers[3];
    PositionComboBox.ItemIndex := Pos;
  end;

  procedure InitLines;
  var
    List: TStringList;
    I: Integer;
    Cmd: TJSONObject = nil;
    Params: TJSONArray = nil;
  begin
    List := TStringList.Create;

    I := ListIndex + 1;
    while I < EcList.Count do begin
      Cmd := EcList.Objects[I];

      if Cmd = nil then
         Break;
      if Cmd.Integers['code'] <> SHOW_MESSAGE_LINE_EC_CODE then
         Break;

      if Cmd.Find('parameters', Params) and (Params.Count >= 1) and
           (Params[0].JSONType = jtString) then
        List.Add(Params.Strings[0])
      else
        List.Add('');

      Inc(I);
    end;

    TextMemo.Text := List.Text;

    List.Free;
  end;

begin
  InitialSetUp;
  InitSettings;
  InitLines;

  UpdateFace;
end;

procedure TECShowMessageFrame.MakeResultingCommand;

  function CreateStartingCommand: TJSONObject;
  begin
    CreateStartingCommand := TJSONObject.Create([
      'code', SHOW_MESSAGE_START_EC_CODE,
      'indent', Indent,
      'parameters', TJSONArray.Create([
                                       FaceFilename,
                                       FaceIndex,
                                       BackgroundComboBox.ItemIndex,
                                       PositionComboBox.ItemIndex
                    ])
    ]);
  end;

var
  List: TStringList;
  I: Integer;
begin
  ResultingCommand := TJSONArray.Create([CreateStartingCommand]);

  List := TStringList.Create();
  List.Text := TextMemo.Text;
  for I := 0 to List.Count -1 do begin
    if (I > 0) and (I mod 4 = 0) and BatchEntryCheckBox.Checked then
       ResultingCommand.Add(CreateStartingCommand);

    ResultingCommand.Add(TJSONObject.Create([
      'code', SHOW_MESSAGE_LINE_EC_CODE,
      'indent', Indent,
      'parameters', TJSONArray.Create([List[I]])
    ]));
  end;
  List.Free;
end;

procedure TECShowMessageFrame.UpdateLanguage(Code: String);
begin
  inherited UpdateLanguage(Code);

  if IsLanguageRtl(Code) then begin
    TextSizePanel.Anchors := [akTop, akBottom, akRight];
    BiDiMode := bdRightToLeft;
  end else begin
    TextSizePanel.Anchors := [akTop, akBottom, akLeft];
    BiDiMode := bdLeftToRight;
  end;
end;

end.

